﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Data.SqlClient;
using SSRSViewer.Core;

namespace SSRSViewer
{
    public class RdlReportParameter
		: IRdlReportParameter
    {
        IDbConnection _Connection { get; set; }
        object _ParameterEntryUserControl;
        RdlDataProvider _LookupProvider { get; set; }
        RdlValidValuesParser _ValidValuesParser { get; set; }
        RdlDefaultValuesParser _DefaultValuesParser { get; set; }
        string _DataType { get; set; }
        bool _MultiValue { get; set; }
        bool _AllowBlank { get; set; }


        public string Name { get; private set; }
        public string Prompt { get; private set; }
        public object ParameterEntryUserControl { get { return _ParameterEntryUserControl; } }
        public object Value
        {
            get { return (_ParameterEntryUserControl as IParameterEditor).EditValue; }
            set { (_ParameterEntryUserControl as IParameterEditor).EditValue = value; }
        }
        public DbType GetSqlType
        {
            get
            {
                if (_ParameterEntryUserControl is MultipleValidValuesUserControl)
                    return DbType.Object;
                else
                    switch (_DataType)
                    {
                        case "Boolean":
                            return DbType.Boolean;
                        case "DateTime":
                            return DbType.DateTime;
                        case "Float":
                            return DbType.Decimal;
                        case "Integer":
                            return DbType.Int32;
                        case "String":
                            return DbType.String;
                        default:
                            return DbType.String;
                    }
            }
        }
        public Type GetClrType
        {
            get
            {
                switch (_DataType)
                {
                    case "Boolean":
                        return typeof(Boolean);
                    case "DateTime":
                        return typeof(DateTime);
                    case "Float":
                        return typeof(decimal);
                    case "Integer":
                        return typeof(int);
                    case "String":
                        return typeof(string);
                    default:
                        return typeof(string);
                }
            }
        }

        public RdlReportParameter(IDbConnection cn, XmlNode parameterNode, IList<RdlDataProvider> providers)
        {
            ParseNode(parameterNode);
            _Connection = cn;

            if (_ValidValuesParser != null)
                _LookupProvider = providers.Where(p => p.Name == _ValidValuesParser.DatasetName).SingleOrDefault();

            InitializeEditor();
        }

        void ParseNode(XmlNode parameterNode)
        {
            Name = parameterNode.Attributes["Name"].Value;
            foreach (XmlNode paramInfo in parameterNode.ChildNodes)
            {
                switch (paramInfo.Name)
                {
                    case "DataType":
                        _DataType = paramInfo.InnerText;
                        break;
                    case "Prompt":
                        Prompt = paramInfo.InnerText;
                        break;
                    case "ValidValues":
                        _ValidValuesParser = new RdlValidValuesParser(paramInfo);
                        break;
                    case "MultiValue":
                        _MultiValue = Convert.ToBoolean(paramInfo.InnerText);
                        break;
                    case "AllowBlank":
                        _AllowBlank = Convert.ToBoolean(paramInfo.InnerText);
                        break;
                    case "DefaultValue":
                        _DefaultValuesParser = new RdlDefaultValuesParser(paramInfo);
                        break;
                }
            }
        }
        void InitializeEditor()
        {
            if (_MultiValue)
            {
                MultipleValidValuesUserControl control = new MultipleValidValuesUserControl();
                control.Prompt = Prompt;
                control.ValuesParser = _ValidValuesParser;
                control.DataProvider = _LookupProvider;
                control.Connection = (SqlConnection)_Connection;
                control.EditingParameter = this;
                control.Initialize();
                _ParameterEntryUserControl = control;
            }
            else
            {
                if (_LookupProvider != null)
                {
                    SingleValidValueUserControl control = new SingleValidValueUserControl();
                    control.Prompt = Prompt;
                    control.DataProvider = _LookupProvider;
                    control.Connection = (SqlConnection)_Connection;
                    control.ValuesParser = _ValidValuesParser;
                    control.EditingParameter = this;
                    control.Initialize();
                    _ParameterEntryUserControl = control;
                }
                else
                {
                    switch (_DataType)
                    {
                        case "Boolean":
                            _ParameterEntryUserControl = new BooleanParameterUserControl() { Prompt = Prompt, EditingParameter = this };
                            break;
                        case "DateTime":
                            _ParameterEntryUserControl = new DateParameterUserControl() { Prompt = Prompt, EditingParameter = this };
                            break;
                        case "Integer":
                            _ParameterEntryUserControl = new IntegerParameterUserControl() { Prompt = Prompt, EditingParameter = this };
                            break;
                        case "Float":
                            _ParameterEntryUserControl = new FloatParameterUserControl() { Prompt = Prompt, EditingParameter = this };
                            break;
                        case "String":
                            _ParameterEntryUserControl = new StringParameterUserControl() { Prompt = Prompt, EditingParameter = this };
                            break;
                    }
                }
            }
        }
    }
}
